﻿using Blm.PgsqlDriver.Helpers;
using Language.Resource;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Localization;
using Npgsql;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using VisionCloud.Core.Model.Enums;
using VisionCloud.Domain.Common;
using VisionCloud.Domain.DtoModel.Applet.RequestDto;
using VisionCloud.Domain.DtoModel.Applet.ResponseDto;
using VisionCloud.Domain.DtoModel.Ms;
using VisionCloud.Domain.Repository.Interface.Ms;
using VisionCloud.Service.Ms;
using VisionCloud.Utility;

namespace VisionCloud.Service.Applet
{
    public class ReportService
    {
        public IMsTaskRepository MsTaskRepository { get; set; }

        public ICSMSTaskRepository CSMSTaskRepository { get; set; }

        public IMsPointCompletedRepository MsPointCompletedRepository { get; set; }

        public IMsHouseMapDetailsRepository MsHouseMapDetailsRepository { get; set; }

        public IMsTaskPointsRepository MsTaskPointsRepository { get; set; }

        /// <summary>
        /// 多语言资源
        /// </summary>
        public IStringLocalizer<ServiceResource> Localizer { get; set; }

        public async Task<PointReportConditionDto> GetPointReportCondition(QueryReportConditionDto condition)
        {
            var result = new PointReportConditionDto();

            result.CompletedPoints = condition.MeasureType switch
            {
                MeasureTypeEnum.实测实量任务 => await MsPointCompletedRepository.GetCompeltedPointsByFloor(condition),
                MeasureTypeEnum.建模任务 or MeasureTypeEnum.外立面任务 => await MsTaskPointsRepository.GetFinishedPointIndex(condition),
                _ => new List<int>()
            };

            if (result.CompletedPoints.Count > 0)
            {
                result.CompletedPoints = result.CompletedPoints.OrderBy(x => x).ToList();

                //工程阶段
                result.ProjectStandards = await GetProjectStandards();

                //日期
                foreach (var dateCon in Enum.GetValues(typeof(DateConditionEnum)))
                {
                    result.DateConditions.Add(new TextValue((int)dateCon, dateCon.ToString()));
                }

                (List<TaskTypeEnum> TaskTypes, List<string> TaskProperties) = await GetTaskTpyeAndProperty();

                //任务类型
                foreach (var taskType in TaskTypes)
                {
                    result.TaskTypes.Add(new TextValue((int)taskType, taskType.ToString()));
                }
                result.TaskTypes.Add(new TextValue());

                //检测阶段
                foreach (var taskProperty in TaskProperties)
                {
                    result.TaskPropertys.Add(new TextValue(GetTaskProperty(taskProperty)));
                }

                result.TaskPropertys.Add(new TextValue());
            }

            return result;

            #region 本地方法

            string GetTaskProperty(string taskProperty)
            {
                return condition.MeasureType switch
                {
                    MeasureTypeEnum.实测实量任务 => (taskProperty == TaskPropertyEnum.初测.ToString() || taskProperty == TaskPropertyEnum.复测.ToString()) ? taskProperty : TaskPropertyEnum.其他.ToString(),
                    MeasureTypeEnum.建模任务 or MeasureTypeEnum.外立面任务 => taskProperty,
                    _ => taskProperty,
                };
            }

            async Task<List<TextValue>> GetProjectStandards()
            {
                var list = (await CSMSTaskRepository.WhereAsNoTrackingAsync(x => x.ProjectId == condition.ProjectId && !x.IsDeleted && x.MeasureType == ((int)condition.MeasureType).ToString() && x.BuildingName == condition.Building && x.FloorName == condition.Floor)).Select(x => x.ProjectStage).Distinct().OrderBy(x => x).Select(x => new TextValue(x)).ToList();
                list.Add(new TextValue());
                return list;
            }

            async Task<(List<TaskTypeEnum> TaskTypes, List<string> TaskProperties)> GetTaskTpyeAndProperty()
            {
                (List<TaskTypeEnum> TaskTypes, List<string> TaskProperties) = (new List<TaskTypeEnum>(), new List<string>());
                var list = await MsTaskRepository.GetAll().Where(x => x.ProjectId == condition.ProjectId && !x.IsDeleted && x.MeasureType == ((int)condition.MeasureType).ToString()).Select(x => new { x.TaskType, x.TaskProperty }).Distinct().ToListAsync();
                foreach (var item in list)
                {
                    if (!TaskTypes.Contains(item.TaskType))
                    {
                        TaskTypes.Add(item.TaskType);
                    }
                    if (!TaskProperties.Contains(item.TaskProperty))
                    {
                        TaskProperties.Add(item.TaskProperty);
                    }
                }
                return (TaskTypes, TaskProperties);
            }

            #endregion 本地方法
        }

        public async Task<HouseMapPointsdto> GetHouseMapPoints(QueryHouseMapDto condition)
        {
            return await MsHouseMapDetailsRepository.GetHouseMapByFloor(condition);
        }

        /// <summary>
        /// 获取站点报告列表
        /// </summary>
        /// <param name="condition"></param>
        /// <returns></returns>
        public async Task<PointReportListDto> GetPointReports(QueryPointReportDto condition)
        {
            PointReportListDto result = await MsPointCompletedRepository.GetPointReportList(condition);

            if (condition.MeasureType == MeasureTypeEnum.实测实量任务)
            {
                foreach (var item in result.PointReports)
                {
                    #region 3D热力图

                    //站点目录
                    var pointDic = $"{item.TaskId}_{item.PointIndex}";
                    //baseHotMap目录
                    item.Url = item.ResultDataFilePath;
                    var basePath = Path.Combine(item.ResultDataFilePath, item.TaskName, MsTaskService.DefaultHotMapDir, pointDic);
                    var hotMapPath = Path.Combine(basePath, "baseHotMap");
                    //3D目录
                    var threePath = Path.Combine(item.ResultDataFilePath, item.TaskName, "3D", pointDic);
                    // 3DSetting.ini文件
                    var settingFile = Path.Combine(item.ResultDataFilePath, item.TaskName, "3D", "3DSetting.ini");
                    // 3D目录、baseHotMap目录和3DSetting.ini都存在时才激活3D按钮
                    item.HasHotMap = Directory.Exists(basePath) && Directory.Exists(hotMapPath) && Directory.Exists(threePath) && File.Exists(settingFile);

                    #endregion 3D热力图

                    #region 汇总测量报告

                    int pIndex = item.ResultDataFilePath.IndexOf("task-report-data");
                    if (pIndex == -1)
                    {
                        throw new OperationException(Localizer["YB0188"].Value);
                    }

                    string summaryReportPdfUrl = Path.Combine(item.ResultDataFilePath, item.TaskName, "测量报告", "测量报告.pdf").Replace(@"\", @"/");
                    // 文件不存在按照新命名规范找
                    if (!File.Exists(summaryReportPdfUrl))
                    {
                        string path = Path.Combine(item.ResultDataFilePath, item.TaskName, "测量报告");
                        if (Directory.Exists(path))
                        {
                            var files = Directory.GetFiles(path, "*_汇总报告.pdf");
                            if (files != null && files.Length > 0)
                            {
                                summaryReportPdfUrl = files[0];
                            }
                        }
                        else
                        {
                            Logger.Error($"GetReportList：汇总报告不存在{path}");
                        }
                    }
                    if (pIndex >= 0)
                    {
                        item.Url = StatisService.ToTaskReportUrl(summaryReportPdfUrl.Substring(pIndex));
                    }

                    #endregion 汇总测量报告
                }
            }
            else if (condition.MeasureType == MeasureTypeEnum.建模任务)
            {
                result.PointReports.ForEach(p => p.HasHotMap = true);
            }

            return result;
        }

        public async Task<List<WxRecentlyReportResponse>> GetRencentlyReports(QueryRencentlyReportDto condition)
        {
            DateTime dateCondition = condition.DateCondition switch
            {
                DateConditionEnum.不限 => DateTime.MinValue,
                DateConditionEnum.近一周 => DateTime.Now.AddDays(-7),
                DateConditionEnum.近一个月 => DateTime.Now.AddMonths(-1),
                DateConditionEnum.近半年 => DateTime.Now.AddMonths(-6),
                _ => DateTime.MinValue,
            };
            string whereCondition = string.Empty;
            string sql = string.Empty;
            List<NpgsqlParameter> paras = null;
            var user = OperatorProvider.Get();
            if (!user.IsCompanyAdmin)
            {
                // 非公司管理员角色获取关联项目数据
                paras = new List<NpgsqlParameter>()
                {
                    new NpgsqlParameter("@YunUserGuid", OperatorProvider.Get().Id),
                };

                // 取用户关联项目
                sql = string.Format(VisionCloudGlobalContext.GetSection("sqls:sql:query_relation_projects_with_company01"));
                var list = await PgSqlHelper.QueryListAsync<ProjectIdDto>(sql, paras.ToArray());
                var projectIds = list.Select(x => x.ProjectId).ToList();
                foreach (var item in projectIds)
                {
                    whereCondition += $"'{item}',";
                }
                if (string.IsNullOrEmpty(whereCondition))
                {
                    // 无关联项目
                    return null;
                }

                whereCondition = whereCondition.Substring(0, whereCondition.Length - 1);
                whereCondition = $" AND T2.\"ProjectId\" IN ({whereCondition})";
            }
            paras = new List<NpgsqlParameter>()
            {
                    new NpgsqlParameter("@CompanyGuid", OperatorProvider.Get().CompanyGuid),
                    new NpgsqlParameter("@ReportUploadDateTime", dateCondition),
                    new NpgsqlParameter("@MeasureType", ((int)condition.MeasureType).ToString()),
            };

            // 取用户管理报告数据
            sql = string.Format(VisionCloudGlobalContext.GetSection("sqls:sql:query_wx_rencently_reports"), whereCondition);
            var reportResponses = await PgSqlHelper.QueryListAsync<WxRecentlyReportResponse>(sql, paras.ToArray());
            return reportResponses;
        }
    }
}